#include "TransactionIO.h"

/* Function Prototype */
void printInvoiceNo(ostream &output, int invoiceNo);
void printEntry(ostream &output, string produceID, int quantity, int unitPrice);
void printSummary(ostream &output, int totalPrice, string transactionTime);
void displayErrorMessage(string errorMsg);

/* Constructor for Transaction IO */
TransactionIO::TransactionIO(string path)
{
	filePath = path;
	
	/* Initialize a File Writer */
	outputFileStream.open("Transaction.txt", ios::out | ios::app);
	if(!outputFileStream) 
		displayErrorMessage("Error Message: Fail to open file\n");
}

/* Destructor for Transaction IO */
TransactionIO::~TransactionIO()
{
	filePath.clear();
	outputFileStream.close();
}

/* Return the Last Invoice Number */
int TransactionIO::getLastInvoiceNo()
{
	ifstream readFromFile(filePath, ios::in);
	string data;
	int lastInvoiceNo;

	while(getline(readFromFile, data))
		if(data.find(';') == string::npos)
			lastInvoiceNo = atoi(data.c_str());

	readFromFile.close();

	return lastInvoiceNo;
}

/* Write Invoice Number to Text File */
void TransactionIO::newInvoiceNo(int invoiceNo)
{
	printInvoiceNo(outputFileStream, invoiceNo);
}

/* Write Entry to Text File */
void TransactionIO::newEntry(string produceID, int quantity, int unitPrice)
{
	printEntry(outputFileStream, produceID, quantity, unitPrice);
}

/* Write New Summary to Text File */
void TransactionIO::newSummary(int totalPrice, string transactionTime)
{
	printSummary(outputFileStream, totalPrice, transactionTime);
}

/* Search the Detail of Transaction by Invoice Number
Assume the invoiceNo must be unique */
void TransactionIO::checkTransactionDetail(int invoiceNo)
{
	ifstream readFromFile(filePath, ios::in);
	string data;
	bool found = false;

	/* Search the Target Transaction Detail */
	while(getline(readFromFile, data) && !found)
	{
		if(data.find(';') == string::npos){
			int transactionIndex = atoi(data.c_str());
			if(transactionIndex == invoiceNo)
			{
				found = true;
				vector<string> sub_datas;
				while(getline(readFromFile, data) && data.find(';') != string::npos)
				{
					stringstream ss(data);
					string sub_data;
					while(getline(ss, sub_data, ';'))
						sub_datas.push_back(sub_data);
				}

				/* Print the Summary Detail */
				cout << "-------------------  INVOICE SUMMARY  ------------------------" << endl;
				cout << "Invoice Number: " << transactionIndex << endl;
				cout << "--------------------------------------------------------------" << endl;
				for (int i = 0; i < (sub_datas.size()/3); i++)
				{
					cout << "Product ID: " << sub_datas[i*3] << "\t"
						<< "Quantity: " << sub_datas[i*3+1] << "\t"
						<< "Unit Price: " << sub_datas[i*3+2] << endl;
					cout << "--------------------------------------------------------------" << endl;
				}
				cout << "Total Price: " << sub_datas[sub_datas.size()-2] << "\t"
					<< "Transaction Time: " << sub_datas[sub_datas.size()-1] << endl;
				cout << "--------------------------------------------------------------" << endl;
			}
		}
	}
	// Display error message when the input invoice number is not found
	if(!found)
		cerr << "Error Message: The invoice no is empty.\n";

	readFromFile.close();
}

/* Display Error Message */
void TransactionIO::displayErrorMessage(string errorMsg)
{
	cerr << errorMsg << endl;
	exit(1);
}

/* Format the output of print Invoice Number */
void printInvoiceNo(ostream &output, int invoiceNo)
{
	output << invoiceNo << endl;
}

/* Format the output of Entry Printing */
void printEntry(ostream &output, string productID, int quantity, int unitPrice)
{
	output << productID << ";" << quantity << ";" << unitPrice << endl;
}

/* Format the output of Summary Printing */
void printSummary(ostream &output, int totalPrice, string transactionTime)
{
	output << totalPrice << ";" << transactionTime << endl;
} 

